Skip to content

feat(mcp): suspend the agent job on a UiPath MCP task#905

Closed
edis-uipath wants to merge 1 commit into
chore/upgrade-mcp-1.27.2from
feat/mcp-suspend-on-uipath-task
Closed

feat(mcp): suspend the agent job on a UiPath MCP task#905
edis-uipath wants to merge 1 commit into
chore/upgrade-mcp-1.27.2from
feat/mcp-suspend-on-uipath-task

Conversation

@edis-uipath

Copy link
Copy Markdown
Contributor

Suspend the agent job on a UiPath MCP task

Stacked on #904 (mcp 1.27.2). When an MCP tool advertises task support and the call starts a UiPath Orchestrator job, the agent now suspends until the child job completes — instead of blocking on tasks/result — reusing the exact suspend/resume path process_tool already uses.

Flow

  1. A task-augmentable tool (per AgentMcpTool.execution.taskSupport = optional/required) is invoked.
  2. McpClient.call_tool_as_task sends a task-augmented tools/call (params.task) and parses the CreateTaskResult (the Python SDK has no client task helper, so it sends the raw request via send_request).
  3. The result's _meta marks it as a UiPath job (uipath.com/source=orchestrator, jobKey, folderKey).
  4. @durable_interruptinterrupt(WaitJobRaw(job=Job(key=jobKey, folder_key=folderKey), process_folder_key=folderKey)). The runtime persists a JOB_RAW resume trigger, Orchestrator suspends the parent job, and on child completion resumes with the job's output.

Non-task tools are unchanged (synchronous call_tool, 404-retry).

Where task support comes from

⚠️ Cross-package dependencies (this PR is the top of a stack)

  • uipath-python #1716 — adds AgentMcpTool.execution.taskSupport. CI here is red until that publishes and the lock picks it up (the import resolves then). Bump the uipath floor to that release before merge.
  • AgentHubService — stamps the task result _meta marker and must emit a ttl on the task object (the official Python Task.ttl is required, so the CreateTaskResult won't parse without it).

Testing

  • Detection (optional/required ⇒ task; forbidden/absent ⇒ not), execution mapping from a server Tool, call_tool_as_task request shape, and the suspend path (asserts WaitJobRaw carries the job/folder keys from _meta and resume returns the job output).
  • Full test_mcp suite green (67); ruff + mypy clean. (Run locally against an editable uipath-python #1716.)

🤖 Generated with Claude Code

When an MCP tool advertises task support (execution.taskSupport optional/required) and the
call starts a UiPath Orchestrator job, the agent now suspends until the child job completes
— instead of blocking on tasks/result — reusing the exact process_tool suspend/resume path.

- McpClient.call_tool_as_task: sends a task-augmented tools/call (params.task) and parses the
  CreateTaskResult (the Python SDK has no client task helper, so it sends the raw request).
- mcp_tool: task-augmentable tools (per AgentMcpTool.execution.taskSupport, also mapped from
  dynamic-discovery Tool.execution) invoke @durable_interrupt -> read the result's _meta
  (uipath.com/source=orchestrator, jobKey, folderKey) -> interrupt(WaitJobRaw(...)). The runtime
  persists a JOB_RAW resume trigger, Orchestrator suspends the parent, and on completion resumes
  with the child job's output. Non-task tools are unchanged.

Depends on:
- uipath-python: AgentMcpTool.execution.taskSupport (UiPath/uipath-python#1716) — needed for the
  cached discovery path; CI is red until that publishes and the lock picks it up.
- AgentHubService task result _meta marker + a `ttl` on the task (so the result parses here).

Tests: detection (optional/required vs forbidden/none), execution mapping from a server Tool,
call_tool_as_task request shape, and the suspend path (asserts WaitJobRaw carries job/folder keys
and resume returns the job output). Full mcp suite green (67).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 14, 2026 08:01

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds MCP “task” execution support for UiPath-backed MCP tools so that when a task starts a UiPath Orchestrator job, the agent suspends and resumes via the existing durable interrupt path (instead of blocking on task polling), aligning MCP tool execution with the process_tool job model.

Changes:

  • Map MCP server Tool.execution.taskSupport into AgentMcpTool.execution and detect task-augmentable tools (optional/required).
  • Add McpClient.call_tool_as_task() to send task-augmented tools/call requests and receive a CreateTaskResult handle.
  • Implement suspend/resume behavior for UiPath-marked tasks by interrupting with WaitJobRaw and returning parsed job output; add tests covering detection, request shape, and suspend path.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/uipath_langchain/agent/tools/mcp/mcp_tool.py Adds taskSupport mapping/detection and the suspend-on-UiPath-task execution path using WaitJobRaw + durable interrupt.
src/uipath_langchain/agent/tools/mcp/mcp_client.py Adds a raw task-augmented tools/call helper (call_tool_as_task) using send_request.
tests/agent/tools/test_mcp/test_mcp_task_suspend.py New tests validating task detection, request augmentation, and suspend/resume behavior.

Comment on lines +257 to +277
meta = create_result.meta or {}
if meta.get(_UIPATH_SOURCE_META_KEY) != _UIPATH_ORCHESTRATOR_SOURCE:
raise AgentRuntimeError(
code=AgentRuntimeErrorCode.UNEXPECTED_ERROR,
title=f"Tool '{mcp_tool.name}' did not start a UiPath job",
detail=(
"The MCP server returned a task that is not a UiPath Orchestrator job "
"(missing the uipath.com/source marker), which is not supported."
),
)

return WaitJobRaw(
# The resume trigger keys off the job's GUID key (item_key = job.key) and re-fetches the
# job on resume; the numeric id is required by the model but unused here, hence the 0.
job=Job(
id=0,
key=meta.get(_UIPATH_JOB_KEY_META_KEY),
folder_key=meta.get(_UIPATH_FOLDER_KEY_META_KEY),
),
process_folder_key=meta.get(_UIPATH_FOLDER_KEY_META_KEY),
)
Comment on lines 7 to 11
from uipath.agent.models.agent import (
AgentMcpResourceConfig,
AgentMcpTool,
AgentMcpToolExecution,
CachedToolsConfig,
Comment on lines +23 to +28
def _mcp_tool(task_support: str | None) -> AgentMcpTool:
data: dict = {
"name": "invoke-process",
"description": "Run a process",
"inputSchema": {"type": "object", "properties": {}},
}
@edis-uipath

Copy link
Copy Markdown
Contributor Author

we will wait to see where tasks land before doing this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants